package io.renren.service.impl.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.utils.Constant;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;
import io.renren.dao.SeatApplicationDao;
import io.renren.entity.SeatApplicationEntity;
import io.renren.entity.SeatEntity;
import io.renren.entity.SysDictEntity;
import io.renren.param.SysDictQueryParam;
import io.renren.service.SeatApplicationService;
import io.renren.service.SeatService;
import io.renren.service.SysDictService;
import io.renren.vo.SeatApplicationVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


@Service("seatApplicationService")
public class SeatApplicationServiceImpl extends ServiceImpl<SeatApplicationDao, SeatApplicationEntity> implements SeatApplicationService {

    @Autowired
    private SeatService seatService;
    @Autowired
    private SeatApplicationDao seatApplicationDao;
    @Autowired
    private SysDictService sysDictService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String employeeId = null, startTime = null, endTime = null, compId = null;
        Long seatId;
        List<Long> seatIds = new ArrayList<>();
        employeeId = (String) params.get("employeeId");
        seatId = (Long) params.get("seatId");
        compId = (String) params.get("compId");
        seatIds = (List<Long>) params.get("seatIds");
        if (params.get("startTime") != null) {
            startTime = DateUtil.format((Date) params.get("startTime"), DatePattern.NORM_DATETIME_PATTERN);
        }
        if (params.get("endTime") != null) {
            endTime = DateUtil.format((Date) params.get("endTime"), DatePattern.NORM_DATETIME_PATTERN);
        }
        List<String> states = new ArrayList<>();
        states.add(Constant.ApplicationState.APPLIED.getValue());
        states.add(Constant.ApplicationState.STARTED.getValue());

        IPage<SeatApplicationEntity> page = null;
        if (startTime != null && startTime != null) {
            String finalStartTime = startTime;
            String finalEndTime = endTime;
            page = this.page(
                    new Query<SeatApplicationEntity>().getPage(params),
                    new QueryWrapper<SeatApplicationEntity>()
                            .like(employeeId != null && StringUtils.isNotBlank(employeeId), "employee_id", employeeId)
                            .in(states != null && states.size() > 0, "state", states)
                            .eq(seatId != null && seatId > 0, "seat_id", seatId)
                            .eq(compId != null, "comp_id", compId)
                            .in(CollectionUtil.isNotEmpty(seatIds) && seatIds.size() > 0, "seat_id", seatIds)
                            .and(qw1 -> qw1.lt("start_time", finalStartTime).gt("end_time", finalStartTime)
                                    .or(qw3 -> qw3.le("start_time", finalEndTime).ge("end_time", finalEndTime)))
            );
        } else {
            page = this.page(
                    new Query<SeatApplicationEntity>().getPage(params),
                    new QueryWrapper<SeatApplicationEntity>()
                            .like(employeeId != null && StringUtils.isNotBlank(employeeId), "employee_id", employeeId)
                            .in(states != null && states.size() > 0, "state", states)
                            .eq(seatId != null && seatId > 0, "seat_id", seatId)
                            .eq(compId != null, "comp_id", compId)
                            .in(CollectionUtil.isNotEmpty(seatIds) && seatIds.size() > 0, "seat_id", seatIds)
            );
        }

        List<SeatApplicationVo> vos = SeatApplicationVo.convertFor(page.getRecords());
        List<SeatApplicationVo> retVos = new ArrayList<>();

        for (SeatApplicationVo vo : vos) {

            SysDictQueryParam dictQueryByNameCodeParam = new SysDictQueryParam();
            dictQueryByNameCodeParam.setName("seatApplicationState");
            dictQueryByNameCodeParam.setCode(vo.getState());
            SysDictEntity dictEntity = sysDictService.queryByNameCode(dictQueryByNameCodeParam);
            vo.setState(dictEntity.getValue());

            SeatEntity seatEntity = seatService.getById(vo.getSeatId());
            if (seatEntity == null || "fixed".equals(seatEntity.getType())) {
                continue;
            }
            vo.setSeatCode(seatEntity.getCode());
            retVos.add(vo);
        }

        return new PageUtils(retVos, retVos.size(), 100, 1);
    }

    public List<SeatApplicationEntity> queryUnfinish(Long seatId) {
        List<String> states = new ArrayList<>();
        states.add(Constant.ApplicationState.APPLIED.getValue());
        states.add(Constant.ApplicationState.STARTED.getValue());

        QueryWrapper<SeatApplicationEntity> queryWrapper = new QueryWrapper<SeatApplicationEntity>()
                .eq(seatId != null, "seat_id", seatId)
                .in("state", states);

        List<SeatApplicationEntity> seatApplicationEntities = seatApplicationDao.selectList(queryWrapper);

        return seatApplicationEntities;
    }

    public List<SeatApplicationEntity> queryBySeatId(Long seatId) {

        QueryWrapper<SeatApplicationEntity> queryWrapper = new QueryWrapper<SeatApplicationEntity>()
                .eq(seatId != null, "seat_id", seatId);

        List<SeatApplicationEntity> seatApplicationEntities = seatApplicationDao.selectList(queryWrapper);

        return seatApplicationEntities;
    }

    public List<SeatApplicationEntity> queryByCompId(String compId) {
        List<String> states = new ArrayList<>();
        states.add(Constant.ApplicationState.APPLIED.getValue());
        states.add(Constant.ApplicationState.STARTED.getValue());

        QueryWrapper<SeatApplicationEntity> queryWrapper = new QueryWrapper<SeatApplicationEntity>()
                .eq(compId != null, "comp_id", compId)
                .in(states != null && states.size() > 0, "state", states);

        List<SeatApplicationEntity> seatApplicationEntities = seatApplicationDao.selectList(queryWrapper);

        return seatApplicationEntities;
    }


}
